/*
 * Copyright (C) 2008-2011 University of Deusto
 * 
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.
 * 
 * This software consists of contributions made by many individuals, 
 * listed below:
 *
 * Author: Aitor Gómez Goiri <aitor.gomez@deusto.es>
 */
package otso.se.network.sockets.communication.abstraction.tcp;

import java.util.concurrent.Callable;

import org.restlet.data.Status;
import org.restlet.resource.ResourceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import otso.se.network.sockets.communication.abstraction.HttpRequest;
import otso.se.network.sockets.communication.abstraction.HttpRequest.Operation;
import otso.se.network.sockets.communication.abstraction.HttpResponse;

public class HttpSocketRequest implements Callable<HttpResponse> {
	final Logger logger = LoggerFactory.getLogger(HttpSocketRequest.class);
	private final TCPClient client = new TCPClient();
	
	private final Operation operation;
	final String host;
	final int port;
	final String path;
    
    public HttpSocketRequest(String url, Operation op) {
    	this.operation = op;
    	final String[] elements = extractElementsFromURL(url);
    	this.host = elements[0];
    	this.port = Integer.valueOf(elements[1]);
    	this.path = elements[2];
    	logger.debug("Host: " + host + ", Port: " + port + ", Url: " + path);
    }
    
    protected String[] extractElementsFromURL(String url) {
    	final String[] elements = new String[3];
    	
    	String[] split = url.split("://");
    	final String hostAndPort = split[1];
    	split = hostAndPort.split(":");
    	if (split.length==1) {
    		final String[] pieces = extractLastTwoElements(split[0]);
	    	elements[0] = pieces[0];
	    	elements[1] = "80";
	    	elements[2] = pieces[1];
    	} else {
	    	elements[0] = split[0];
	    	
	    	final String[] pieces = extractLastTwoElements(split[1]);
	    	elements[1] = pieces[0];
	    	elements[2] = pieces[1];
    	}
    	
    	return elements;
    }
    
    	private String[] extractLastTwoElements(String base) {
    		final String[] els = new String[2];
    		
    		int splitIn = base.indexOf('/');
    		if (splitIn==-1) {
    			els[0] = base;
    			els[1] = "/";
    		} else {
    			els[0] = base.substring(0, splitIn);
    			els[1] = base.substring(splitIn);
    		}
	    	
	    	return els;
    	}
    	
    protected void start() {
    	this.client.openSocket(this.host, this.port);
    }
    
    protected HttpResponse request(/*Mediatype and*/Operation op) {
    	final Object o = this.client.sendData(new HttpRequest(op, this.path, System.currentTimeMillis()));
    	if (o instanceof HttpResponse) {
    		final HttpResponse response = (HttpResponse) o;
    		if(response.getStatus().isSuccess()) return response;
    		else throw new ResourceException(response.getStatus());
    	}
    	throw new ResourceException(Status.CLIENT_ERROR_NOT_ACCEPTABLE);
    }
    
    protected void stop() {
    	this.client.closeSocket();
    }
    
	@Override
	public HttpResponse call() throws Exception {
		try {
			start();
			return request(this.operation);
		} finally {
			stop();
		}
	}
}